package com.kexun.interceptor;

import com.kexun.annotation.AddToken;
import com.kexun.annotation.CheckToken;
import com.kexun.common.redis.RedisUtil;
import com.kexun.handler.ApiRRException;
import com.kexun.utils.GenerateUUID;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.concurrent.TimeUnit;

/**
 * @author lidong
 * @email 3275208135@qq.com
 * @date 2019年5月16日 下午17:16:02
 */
@Slf4j
public class SecurityInterceptor extends HandlerInterceptorAdapter {

    private RedisUtil redisUtil;

    public static final String LOGIN_USER_KEY = "LOGIN_USER_KEY";
    public static final String LOGIN_TOKEN_KEY = "x-token";

    public SecurityInterceptor(RedisUtil redisUtil) {
        this.redisUtil = redisUtil;
    }


    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

        AddToken addToken;
        CheckToken checkToken;
        if (handler instanceof HandlerMethod) {
            //如果是映射到方法
            HandlerMethod handlerMethod = (HandlerMethod) handler;
            addToken = handlerMethod.getMethodAnnotation(AddToken.class);
            checkToken = handlerMethod.getMethodAnnotation(CheckToken.class);
        } else {
            return true;
        }
        // AddToken 注解向前台cookie保存一个token用于后续授权 保存一个小时
        if (addToken != null) {
            String name = addToken.name();
            String token = GenerateUUID.generate();
            Cookie cookie = new Cookie(name, token);
            cookie.setMaxAge(1000 * 60 * 60);
            cookie.setHttpOnly(true);
            response.addCookie(cookie);
            redisUtil.setEx(name, token, 1, TimeUnit.HOURS);
            log.info("添加token:" + name + " 值:" + token);
        }


        if (checkToken != null) {

            String name = checkToken.name();
            String s = redisUtil.get(name);
            if (StringUtils.isEmpty(s)) {
                throw new ApiRRException("token无效");
            }
            String token = getToken(request, name);
            if (StringUtils.isEmpty(token)) {
                throw new ApiRRException("token缺失");
            }

            if (!s.equals(token)) {
                throw new ApiRRException("token无效");
            }

        }


        return true;
    }


    public String getToken(HttpServletRequest request, String tokenName) {
        Cookie[] cookies = request.getCookies();
        for (Cookie cookie : cookies) {
            String name = cookie.getName();
            if (name.equals(tokenName)) {
                return cookie.getValue();
            }
        }
        return null;
    }
}
